///////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
#include <Math/Vec3f.h>
#include <cmath>

//-----------------------------------------------------------------------------

Vec3f::Vec3f ( )
{
	set ( 0, 0, 0 );
}

//-----------------------------------------------------------------------------

Vec3f::Vec3f ( const f32& x, const f32& y, const f32& z )
{
	set ( x, y, z );
}

//-----------------------------------------------------------------------------

void Vec3f::set ( const f32& x, const f32& y, const f32& z )
{
	this->x = x;
	this->y = y;
	this->z = z;
}

//-----------------------------------------------------------------------------

void Vec3f::setX ( const f32& x)
{
	this->x = x;
}

//-----------------------------------------------------------------------------

void Vec3f::setY ( const f32& y )
{
	this->y = y;
}

//-----------------------------------------------------------------------------

void Vec3f::setZ ( const f32& z )
{
	this->z = z;
}

//-----------------------------------------------------------------------------

f32 Vec3f::getX ()
{
	return x;
}

//-----------------------------------------------------------------------------

f32 Vec3f::getY ()
{
	return y;
}

//-----------------------------------------------------------------------------

f32 Vec3f::getZ ()
{
	return z;
}

//-----------------------------------------------------------------------------

f32 Vec3f::length () 
{
	return sqrt( x*x + y*y + z*z );
}

//-----------------------------------------------------------------------------

void Vec3f::normalize ( )
{
	f32 n = length ();
	x /= n;
	y /= n;
	z /= n;
}

//-----------------------------------------------------------------------------

void Vec3f::add ( const Vec3f& v )
{
	x += v.x;
	y += v.y;
	z += v.z;
}

//-----------------------------------------------------------------------------

void Vec3f::scale ( const f32& s )
{
	x *= s;
	y *= s;
	z *= s;
}

//-----------------------------------------------------------------------------

Vec3f Vec3f::cross ( const Vec3f& v )
{
	Vec3f c;
	c.x = y*v.z - z*v.y;
	c.y = z*v.x - x*v.z;
	c.z = x*v.y - y*v.x;
	return c;
}

//-----------------------------------------------------------------------------

f32 Vec3f::dot ( const Vec3f& v )
{
	return x*v.x + y*v.y + z*v.z;
}

//-----------------------------------------------------------------------------

void Vec3f::transform ( const Matrix4x4& trans )
{
	f32 nx = x*trans.m[0][0] + y*trans.m[1][0] + z*trans.m[2][0];
	f32 ny = x*trans.m[0][1] + y*trans.m[1][1] + z*trans.m[2][1];
	f32 nz = x*trans.m[0][2] + y*trans.m[1][2] + z*trans.m[2][2];
	x = nx;
	y = ny;
	z = nz;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator = (const Vec3f &v)
{
	if ( this != &v )
	{
		this->x = v.x;
		this->y = v.y;
		this->z = v.z;
	}
	return *this;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator = (const f32& val)
{
	this->x = val;
	this->y = val;
	this->z = val;
	return *this;
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator - () const
{
	Vec3f t;
	t.x = -x;
	t.y = -y;
	t.z = -z;
	return t;
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator + (const Vec3f &v) const
{
	return Vec3f(*this) += v;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator += (const Vec3f &v)
{
	this->x += v.x;
	this->y += v.y;
	this->z += v.z;
	return *this;
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator - (const Vec3f &v) const
{
	return Vec3f(*this) -= v;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator -= (const Vec3f &v)
{
	this->x -= v.x;
	this->y -= v.y;
	this->z -= v.z;
	return *this;
}

//-----------------------------------------------------------------------------

const f32 Vec3f::operator * (const Vec3f &v) const
{
	return Vec3f(*this) *= v;
}

//-----------------------------------------------------------------------------

f32 Vec3f::operator *= (const Vec3f &v)
{
	return dot( v );
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator ^ (const Vec3f &v) const
{
	return Vec3f(*this) ^= v;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator ^= (const Vec3f &v)
{
	*this = cross( v );
	return *this;
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator * (const f32& val) const
{
	return Vec3f(*this) *= val;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator *= (const f32& val)
{
	scale( val );
	return *this;
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator / (const f32& val) const
{
	return Vec3f(*this) /= val;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator /= (const f32& val)
{
	*this *= 1.0f / val;
	return *this;
}

//-----------------------------------------------------------------------------

const Vec3f Vec3f::operator * (const Matrix4x4& mat) const
{
	return Vec3f(*this) *= mat;
}

//-----------------------------------------------------------------------------

Vec3f& Vec3f::operator *= (const Matrix4x4& mat)
{
	this->transform( mat );
	return *this;
}

//-----------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////
